<?php

/**
 * 模版各标签的编译类
 * User: xiaoqiang
 * Date: 15-4-9
 * Time: 上午10:00
 */
namespace Library\template;

class LibParse extends LibBase
{
    public $patternString = '[\w|\.]+';


    public $patternParams = '\$[\w|\.]+';

    /**
     * 分组的静态文件列表
     * @var array
     */
    public $groupFiles = [];

    /**
     * 合并后的静态文件名称列表
     * @var array
     */
    public $groupIncludeFiles = [
        'css' => [],
        'js' => []
    ];

    /**
     * 是否进行了包含分组静态文件的操作
     * @var bool
     */
    public $isIncludeGroup = true;

    /**
     * css标签
     * @param $params
     * @param $application
     * @return string
     */
    public function parseCss($params, $application)
    {
        $params = $this->_resourceLabel($params, $application, "css");
        return $params;
    }

    /**
     * js标签
     * @param $params
     * @param $application
     * @return string
     */
    public function parseJs($params, $application)
    {
        $params = $this->_resourceLabel($params, $application, "js");
        return $params;
    }

    /**
     * include标签
     * @param $params
     * @param $application
     * @return string
     */
    public function parseInclude($params, $application)
    {
        $params = LibTools::replaceLabel($params, "include");
        /**
         * @var \LibTemplate $libTemplate
         */
        $libTemplate = \LibTemplate::getInstance();
        if (LibTools::isSyncTemplate($application, $params)) {

            $libTemplate->compile($application, $params);
        }
        $fileName = LibTools::getCacheFileName($application, $params);
        $params = "include '" . $fileName . "'";
        return $params;
    }

    /**
     * for标签
     * @param $params
     * @return mixed
     */
    public function parseFor($params)
    {
        $params = LibTools::replaceLabel($params, "for");
        preg_match('/start\s*=\s*(\w+)/', $params, $starts);
        $start = isset($starts[1]) ? $starts[1] : 0;
        preg_match('/end\s*=\s*([\(|\)|\.|\$|\w]+)/', $params, $ends);
        $end = isset($ends[1]) ? $ends[1] : 0;
        preg_match('/step\s*=\s*(\w+)/', $params, $steps);
        $step = isset($steps[1]) ? $steps[1] : 1;
        preg_match('/equal\s*=\s*(\d)/', $params, $equals);
        $equal = isset($equals[1]) && ($equals[1] == 1) ? "<=" : "<";
        $content = 'for($start=' . $start . ';$start' . $equal . $end . ';$start=$start+' . $step . '){';
        $content = LibTools::format($content, false);
        return $content;
    }

    /**
     * foreach标签
     * @param $params
     * @return mixed|string
     */
    public function parseForeach($params)
    {
        $params = LibTools::replaceLabel($params, "foreach");
        $params = preg_replace('/data=(\$[\w|\.|\[|\]|\.|\"|\']+)/is', "\\1 as", $params);
        $params = preg_replace('/key=(' . $this->patternString . ')/is', "$\\1 =>", $params);
        $params = preg_replace('/item=(' . $this->patternString . ')/is', "$\\1", $params);
        $params = "foreach(" . $params . "){";
        $params = LibTools::format($params, false);
        return $params;
    }

    /**
     * if标签<{if $data.string == $params.str_dd}>
     * @param $params
     * @return mixed|string
     */
    public function parseIf($params)
    {
        return $this->_if($params);
    }

    /**
     * elseif 标签<{elseif $data.string == 2}>
     * @param $params
     * @return mixed|string
     */
    public function parseElseif($params)
    {
        return $this->_if($params);
    }

    /**
     * else标签<{else}>
     * @param $params
     * @return mixed|string
     */
    public function parseElse($params)
    {
        return $this->_if($params);
    }

    /**
     * 输出define定义的变量(<{defined SYS_IMAGE_URL}>)
     * @param $params
     * @return mixed
     */
    public function parseDefined($params)
    {
        $params = LibTools::replaceLabel($params, 'defined');
        $return = "";
        if (isset($params)) {
            $return = 'if(defined("' . $params . '")){';
            $return .= "echo $params;";
            $return .= "}";
        }
        return $return;
    }

    /**
     * assign标签,用户模板内变量的赋值<{assign name='var' value='123'}> <{assign name='var' value='$var.php.data1'}>
     * @param $params
     * @return mixed
     */
    public function parseAssign($params)
    {
        $params = LibTools::replaceLabel($params, 'assign');
        preg_match('/name=\"(' . $this->$patternString . ')\"/', $params, $names);
        preg_match('/value=\"(\$?' . $this->$patternString . ')\"/', $params, $values);
        $names = LibTools::convertParams("$" . $names[1], false);
        $values = LibTools::convertParams($values[1], false);
        $params = $names . "=" . $values;
        return $params;
    }

    /**
     * switch标签<{switch $data}> <{switch 333}>
     * @param $params
     * @return string
     */
    public function parseSwitch($params)
    {
        $name = LibTools::replaceLabel($params, 'switch');
        if ($name{0} == "$") {
            $name = LibTools::convertParams($name, false);
        } else {
            $name = "'" . $name . "'";
        }
        $params = "switch(" . $name . "){";
        return $params;
    }

    /**
     * case标签<{case "343"}>
     * @param $params
     * @return mixed
     */
    public function parseCase($params)
    {
        $params = LibTools::replaceLabel($params, "case");
        preg_match('/\"(.*)\"/is', $params, $result);
        $params = "case ";
        if (is_string($result[1])) {
            $params .= "\"";
        }
        $params .= $result[1];
        if (is_string($result[1])) {
            $params .= "\"";
        }
        $params .= ":";
        return $params;
    }

    /**
     * switch的default标签
     * @return mixed
     */
    public function parseDefault()
    {
        return "default:{";
    }

    /**
     * 多语言输出的标签
     * @param $params
     * @return string
     */
    public function parseLang($params)
    {
        $params = LibTools::replaceLabel($params, "lang");
        return "echo \\LibLanguage::get(\"{$params}\")";
    }

    /**
     * 图片路径的标签
     * @param $params
     * @param $application
     * @return string
     */
    public function parseImg($params, $application)
    {
        $params = LibTools::replaceLabel($params, "img");
        $preg = '/dir\s*=\s*[\"|\'](\w+)[\"|\']/';
        if (preg_match($preg, $params, $dirs)) {
            $application = ucfirst($dirs[1]);
            $filename = trim(preg_replace($preg, "", $params));
        } else {
            $filename = $params;
        }
        $path = "/Application/{$application}/static/{$filename}";
        return "echo \"{$path}\";";
    }

    /**
     * 判断逻辑的编译
     * @param $params
     * @return mixed|string
     */
    private function _if($params)
    {
        $tmpArr = explode(" ", $params);
        $keys = array_shift($tmpArr);
        if ($tmpArr) {
            $tmpStr = implode("",$tmpArr);
            $result = LibTools::format($tmpStr, false);
            $result = $keys . "(" . $result . "){";
        } else {
            $result = $keys . "{";
        }
        if (stripos($params, "else") === 0 || stripos($params, "elseif") === 0) {
            $result = "}" . $result;
        }
        return $result;

    }

    /**
     * js,css等静态资源文件的标签替换
     * @param $content
     * @param $application
     * @param $type
     * @return string
     */
    private function _resourceLabel($content, $application, $type)
    {
        $params = LibTools::replaceLabel($content, $type);
        LibTools::filterSpace($params);
        preg_match('/file=\"([^\"]+)\"/is', $params, $cssFileArr);
        $file = $cssFileArr[1];
        if (preg_match('/.css$/', $file)) {
            if (isset($this->groupFiles['css']) && in_array($file, $this->groupFiles['css'])) {
                if ($this->isIncludeGroup) {
                    return $this->includeGroupFile($application);
                } else {
                    return "";
                }
            }
        } elseif (preg_match('/.js$/', $file)) {
            if (isset($this->groupFiles['js']) && in_array($file, $this->groupFiles['js'])) {
                if ($this->isIncludeGroup) {
                    return $this->includeGroupFile($application);
                } else {
                    return "";
                }
            }
        }
        if ($file{0} != "/") {
            $file = "/" . ucfirst($application) . "/static/" . $file;
        }
        $file = "/Application" . $file;
        if ($type == "css") {
            $params = '<link rel="stylesheet" type="text/css" href="' . $file . '"/>';
        } elseif ($type == "js") {
            $params = ' <script type="text/javascript" src="' . $file . '"></script>';
        }
        return $params;
    }

    public function getStaticList($application, $template)
    {
        $sourceFile = LibTools::getTemplatePath($application, $template);
        $sourceFiles = LibTools::getSourceFileTree($application, $sourceFile, []);
        foreach ($sourceFiles as $file) {
            if (!file_exists($file)) {
                continue;
            }
            $content = file_get_contents($file);
            preg_match_all('/\<\{\s*css\s*file=[\"|\']([^\"\']+)[\"|\']\s*group\s*=\s*(\d+)/', $content, $match);
            foreach ($match[2] as $key => $mat) {
                $this->groupFiles['css'][] = $match[1][$key];
                $file = preg_replace('/.css$/', "", $match[1][$key]);
                if (!isset($this->groupIncludeFiles['css'][$mat])) {
                    $this->groupIncludeFiles['css'][$mat] = $file;
                }
                $this->groupIncludeFiles['css'][$mat] .= ";" . $file;
            }
            preg_match_all('/\<\{\s*js\s*file=[\"|\']([^\"\']+)[\"|\']\s*group\s*=\s*(\d+)/', $content, $match);
            foreach ($match[2] as $key => $mat) {
                $this->groupFiles['js'][] = $match[1][$key];
                $file = preg_replace('/.js$/', "", $match[1][$key]);
                if (!isset($this->groupIncludeFiles['js'][$mat])) {
                    $this->groupIncludeFiles['js'][$mat] = $file;
                }
                $this->groupIncludeFiles['js'][$mat] .= ";" . $file;
            }
        }
    }

    public function includeGroupFile($application)
    {
        $url = '/base/resource?file=' . $application . ";";
        $content = "";
        foreach ($this->groupIncludeFiles['css'] as $file) {
            $content .= '<link rel="stylesheet" type="text/css" href="' . $url . $file . '.css"/>';
        }
        foreach ($this->groupIncludeFiles['js'] as $file) {
            $content .= ' <script type="text/javascript" src="' . $url . $file . '.js"></script>';
        }
        $this->isIncludeGroup = false;
        return $content;
    }
}